1 /* 2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021 3 License: [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License]. 4 Authors: Marcelo S. N. Mancini 5 6 Copyright Marcelo S. N. Mancini 2018 - 2021. 7 Distributed under the CC BY-4.0 License. 8 (See accompanying file LICENSE.txt or copy at 9 https://creativecommons.org/licenses/by/4.0/ 10 */ 11 module hip.event.dispatcher; 12 private: 13 import hip.event.handlers.keyboard; 14 import hip.event.handlers.mouse; 15 import hip.systems.gamepad; 16 import hip.windowing.window; 17 import hip.api.config; 18 19 public: 20 import hip.systems.input; 21 import hip.util.time; 22 import hip.api.input.keyboard; 23 import hip.api.input.button; 24 import hip.api.input.mouse; 25 import hip.api.input.gamepad; 26 import hip.api.renderer.viewport; 27 import hip.api.input.core : IHipInput; 28 29 30 31 package __gshared HipGamepad[] gamepads; 32 33 34 /** 35 * Class used to dispatch the events for the each specific handler. 36 * 37 * In the entire engine, there must be only one dispatcher. But it is possible 38 * to create more mouses and keyboards, but it is not being used yet. 39 */ 40 class EventDispatcher : IHipInput 41 { 42 ulong frameCount; 43 KeyboardHandler keyboard = null; 44 HipMouse mouse = null; 45 HipWindow window; 46 bool* isInUpdate; 47 protected void delegate(uint width, uint height)[] resizeListeners; 48 49 this(HipWindow window, bool* isInUpdate) 50 { 51 this.window = window; 52 this.isInUpdate = isInUpdate; 53 keyboard = new KeyboardHandler(); 54 mouse = new HipMouse(); 55 HipEventQueue.newController(); //Creates controller 0 56 initGamepads(); 57 import hip.windowing.events; 58 59 onKeyDown = (uint key) 60 { 61 try 62 { 63 HipEventQueue.post(0, HipEventQueue.EventType.keyDown, HipEventQueue.Key(getHipKeyFromSystem(key))); 64 } 65 catch(Exception e){assert(false);} 66 }; 67 onKeyUp = (uint key) 68 { 69 try{HipEventQueue.post(0, HipEventQueue.EventType.keyUp, HipEventQueue.Key(getHipKeyFromSystem(key)));} 70 catch(Exception e){assert(false);} 71 }; 72 onMouseMove = (int x, int y) 73 { 74 try{HipEventQueue.post(0, HipEventQueue.EventType.touchMove, HipEventQueue.Touch(0, x, y));} 75 catch(Exception e){assert(false);} 76 }; 77 onMouseUp = (ubyte btn, int x, int y) 78 { 79 try{HipEventQueue.post(0, HipEventQueue.EventType.touchUp, HipEventQueue.Touch(0, x, y));} 80 catch(Exception e){assert(false);} 81 }; 82 onMouseDown = (ubyte btn, int x, int y) 83 { 84 try{HipEventQueue.post(0, HipEventQueue.EventType.touchDown, HipEventQueue.Touch(0, x, y));} 85 catch(Exception e){assert(false);} 86 }; 87 onMouseWheel = (int moveX, int moveY) 88 { 89 try{HipEventQueue.post(0, HipEventQueue.EventType.touchScroll, HipEventQueue.Scroll(moveX, moveY, 0));} 90 catch(Exception e){assert(false);} 91 }; 92 93 onWindowResize = (uint width, uint height) 94 { 95 try{HipEventQueue.post(0, HipEventQueue.EventType.windowResize, HipEventQueue.Resize(width, height));} 96 catch(Exception e){assert(false);} 97 }; 98 onWindowClosed = () 99 { 100 try{HipEventQueue.post(0, HipEventQueue.EventType.exit, true);} 101 catch(Exception e){assert(false);} 102 }; 103 104 } 105 106 bool hasQuit = false; 107 108 final void errUpdateOnly(string name) 109 { 110 // debug 111 { 112 import hip.console.log; 113 bool inUpdate = *isInUpdate; 114 if(!inUpdate) 115 loglnError("API ", name, " can only be used inside update()"); 116 } 117 } 118 119 void handleEvent() 120 { 121 window.pollWindowEvents(); 122 handleHipEvent(); 123 frameCount++; 124 } 125 126 127 void handleHipEvent() 128 { 129 130 //Now poll the cross platform input queue 131 HipEventQueue.InputEvent* ev; 132 while((ev = HipEventQueue.poll(0)) != null) 133 { 134 switch(ev.type) 135 { 136 case HipEventQueue.EventType.windowResize: 137 auto w = ev.get!(HipEventQueue.Resize); 138 foreach(r; resizeListeners) 139 r(w.width, w.height); 140 break; 141 case HipEventQueue.EventType.touchDown: 142 auto t = ev.get!(HipEventQueue.Touch); 143 mouse.setPosition(t.xPos, t.yPos, t.id); 144 mouse.setPressed(HipMouseButton.left, true); 145 break; 146 case HipEventQueue.EventType.touchUp: 147 auto t = ev.get!(HipEventQueue.Touch); 148 mouse.setPosition(t.xPos, t.yPos, t.id); 149 mouse.setPressed(HipMouseButton.left, false); 150 break; 151 case HipEventQueue.EventType.touchMove: 152 auto t = ev.get!(HipEventQueue.Touch); 153 mouse.setPosition(t.xPos, t.yPos, t.id); 154 break; 155 case HipEventQueue.EventType.touchScroll: 156 auto t = ev.get!(HipEventQueue.Scroll); 157 mouse.setScroll(t.x, t.y, t.z); 158 break; 159 case HipEventQueue.EventType.keyDown: 160 import hip.console.log; 161 auto k = ev.get!(HipEventQueue.Key); 162 keyboard.handleKeyDown(cast(HipKey)(k.id)); 163 break; 164 case HipEventQueue.EventType.keyUp: 165 auto k = ev.get!(HipEventQueue.Key); 166 keyboard.handleKeyUp(cast(HipKey)(k.id)); 167 break; 168 case HipEventQueue.EventType.gamepadConnected: 169 import hip.console.log;rawlog("Gamepad connected"); 170 auto g = ev.get!(HipEventQueue.Gamepad); 171 if(g.id+1 > gamepads.length) 172 gamepads~= getNewGamepad(g.type); 173 gamepads[g.id].setConnected(true); 174 break; 175 case HipEventQueue.EventType.gamepadDisconnected: 176 import hip.console.log;rawlog("Gamepad disconnected"); 177 auto g = ev.get!(HipEventQueue.Gamepad); 178 gamepads[g.id].setConnected(false); 179 break; 180 case HipEventQueue.EventType.exit: 181 hasQuit = true; 182 break; 183 default:break; 184 } 185 } 186 187 keyboard.update(); 188 } 189 void pollGamepads(float deltaTime) 190 { 191 foreach (g; gamepads) 192 g.poll(deltaTime); 193 } 194 195 void addOnResizeListener(void delegate(uint width, uint height) onResize) 196 in{assert(onResize !is null, "onResize event must not be null.");} 197 do 198 { 199 resizeListeners~= onResize; 200 } 201 202 ///Public API 203 float[2] getTouchPosition(uint id = 0){return cast(float[2])mouse.getPosition(id);} 204 float[2] getTouchDeltaPosition(uint id = 0){return cast(float[2])mouse.getDeltaPosition(id);} 205 206 float[2] getNormallizedTouchPosition(uint id=0) 207 { 208 import hip.hiprenderer; 209 float[2] ret = cast(float[2])getTouchPosition(id); 210 ret[0]/= HipRenderer.width; 211 ret[1]/= HipRenderer.height; 212 return ret; 213 } 214 215 float[2] getWorldTouchPosition(uint id=0, Viewport vp = null) 216 { 217 import hip.math.utils:clamp; 218 import hip.api.renderer.core; 219 float[2] ret = cast(float[2])getTouchPosition(id); 220 if(vp is null) 221 vp = HipRenderer.getCurrentViewport(); 222 223 ret[0] = clamp(((ret[0] - vp.x) / vp.width) * vp.worldWidth, 0, vp.worldWidth); 224 ret[1] = clamp(((ret[1] - vp.y) / vp.height) * vp.worldHeight, 0, vp.worldHeight); 225 226 227 return ret; 228 } 229 ubyte getMulticlickCount(HipMouseButton btn = HipMouseButton.any, uint id = 0) 230 { 231 errUpdateOnly("getMulticlickCount"); 232 return mouse.getMulticlickCount(btn); 233 } 234 bool isDoubleClicked(HipMouseButton btn = HipMouseButton.any, uint id = 0) 235 { 236 errUpdateOnly("isDoubleClicked"); 237 return mouse.isDoubleClicked(btn); 238 } 239 bool isMouseButtonPressed(HipMouseButton btn = HipMouseButton.any, uint id = 0) 240 { 241 errUpdateOnly("isMouseButtonPressed"); 242 return mouse.isPressed(btn); 243 } 244 bool isMouseButtonJustPressed(HipMouseButton btn = HipMouseButton.any, uint id = 0) 245 { 246 errUpdateOnly("isMouseButtonJustPressed"); 247 return mouse.isJustPressed(btn); 248 } 249 bool isMouseButtonJustReleased(HipMouseButton btn = HipMouseButton.any, uint id = 0) 250 { 251 errUpdateOnly("isMouseButtonJustReleased"); 252 return mouse.isJustReleased(btn); 253 } 254 float[3] getScroll(uint id = 0){return cast(float[3])mouse.getScroll();} 255 bool isKeyPressed(char key, uint id = 0){return keyboard.isKeyPressed(key.toUppercase);} 256 bool isKeyJustPressed(char key, uint id = 0) 257 { 258 errUpdateOnly("isKeyJustPressed"); 259 return keyboard.isKeyJustPressed(key.toUppercase); 260 } 261 bool isKeyJustReleased(char key, uint id = 0) 262 { 263 errUpdateOnly("isKeyJustReleased"); 264 return keyboard.isKeyJustReleased(key.toUppercase); 265 } 266 float getKeyDownTime(char key, uint id = 0) 267 { 268 errUpdateOnly("getKeyDownTime"); 269 return keyboard.getKeyDownTime(key.toUppercase); 270 } 271 float getKeyUpTime(char key, uint id = 0) 272 { 273 errUpdateOnly("getKeyUpTime"); 274 return keyboard.getKeyUpTime(key.toUppercase); 275 } 276 ubyte getGamepadCount(){return cast(ubyte)gamepads.length;} 277 AHipGamepad getGamepad(ubyte id) 278 { 279 if(id >= gamepads.length)return null; 280 return gamepads[id]; 281 } 282 float[3] getAnalog(HipGamepadAnalogs analog, ubyte id = 0) 283 { 284 if(id >= gamepads.length) return cast(float[3])Vector3.zero; 285 return cast(float[3])gamepads[id].getAnalogState(analog); 286 } 287 bool isGamepadButtonPressed(HipGamepadButton btn, ubyte id = 0) 288 { 289 if(id >= gamepads.length) return false; 290 return gamepads[id].isButtonPressed(btn); 291 } 292 bool isGamepadButtonJustPressed(HipGamepadButton btn, ubyte id = 0) 293 { 294 if(id >= gamepads.length) return false; 295 errUpdateOnly("isGamepadButtonJustPressed"); 296 return gamepads[id].isButtonJustPressed(btn); 297 } 298 bool isGamepadButtonJustReleased(HipGamepadButton btn, ubyte id = 0) 299 { 300 if(id >= gamepads.length) return false; 301 errUpdateOnly("isGamepadButtonJustReleased"); 302 return gamepads[id].isButtonJustReleased(btn); 303 } 304 305 bool areGamepadButtonsPressed(scope HipGamepadButton[] btns, ubyte id = 0) 306 { 307 if(id >= gamepads.length) return false; 308 errUpdateOnly("areGamepadButtonsPressed"); 309 return gamepads[id].areButtonsPressed(btns); 310 } 311 bool areGamepadButtonsJustPressed(scope HipGamepadButton[] btns, ubyte id = 0) 312 { 313 if(id >= gamepads.length) return false; 314 errUpdateOnly("areGamepadButtonsJustPressed"); 315 return gamepads[id].areButtonsJustPressed(btns); 316 } 317 bool areGamepadButtonsJustReleased(scope HipGamepadButton[] btns, ubyte id = 0) 318 { 319 if(id >= gamepads.length) return false; 320 errUpdateOnly("areGamepadButtonsJustReleased"); 321 return gamepads[id].areButtonsJustReleased(btns); 322 } 323 324 bool isGamepadWireless(ubyte id = 0) 325 { 326 if(id >= gamepads.length) return false; 327 return gamepads[id].isWireless(); 328 } 329 bool setGamepadVibrating(float vibrationPower, float time, ubyte id = 0) 330 { 331 if(id >= gamepads.length) return false; 332 return gamepads[id].setVibrating(vibrationPower, time); 333 } 334 float getGamepadBatteryStatus(ubyte id = 0) 335 { 336 if(id >= gamepads.length) return 0; 337 return gamepads[id].getBatteryStatus(); 338 } 339 340 void postUpdate() 341 { 342 keyboard.postUpdate(); 343 mouse.postUpdate(); 344 foreach(g; gamepads) 345 g.postUpdate(); 346 } 347 } 348 349 350 version(Windows) 351 { 352 public HipKey getHipKeyFromSystem(uint key) 353 { 354 import hip.windowing.platforms.winlib.keys; 355 ushort k = cast(ushort)(key); 356 assert(k > 0 && k <= ubyte.max, "Key out of range"); 357 switch(k) 358 { 359 case VK_BACK: return HipKey.BACKSPACE; 360 case VK_TAB: return HipKey.TAB; 361 case VK_ESCAPE: return HipKey.ESCAPE; 362 363 364 case VK_SHIFT: return HipKey.SHIFT; 365 case VK_CONTROL: return HipKey.CTRL; 366 case VK_MENU: return HipKey.ALT; 367 case VK_SNAPSHOT: return HipKey.PRINT; 368 369 case VK_RETURN: return HipKey.ENTER; 370 case VK_CAPITAL: return HipKey.CAPSLOCK; 371 case VK_SPACE: return HipKey.SPACE; 372 case VK_PRIOR: return HipKey.PAGE_UP; 373 case VK_NEXT: return HipKey.PAGE_UP; 374 case VK_END: return HipKey.END; 375 case VK_HOME: return HipKey.HOME; 376 case VK_LEFT: return HipKey.ARROW_LEFT; 377 case VK_UP: return HipKey.ARROW_UP; 378 case VK_RIGHT: return HipKey.ARROW_RIGHT; 379 case VK_DOWN: return HipKey.ARROW_DOWN; 380 case VK_INSERT: return HipKey.INSERT; 381 case VK_DELETE: return HipKey.DELETE; 382 //0 383 case 0x30: return HipKey._0; 384 case 0x31: return HipKey._1; 385 case 0x32: return HipKey._2; 386 case 0x33: return HipKey._3; 387 case 0x34: return HipKey._4; 388 case 0x35: return HipKey._5; 389 case 0x36: return HipKey._6; 390 case 0x37: return HipKey._7; 391 case 0x38: return HipKey._8; 392 case 0x39: return HipKey._9; 393 //A 394 case 0x41: return HipKey.A; 395 case 0x42: return HipKey.B; 396 case 0x43: return HipKey.C; 397 case 0x44: return HipKey.D; 398 case 0x45: return HipKey.E; 399 case 0x46: return HipKey.F; 400 case 0x47: return HipKey.G; 401 case 0x48: return HipKey.H; 402 case 0x49: return HipKey.I; 403 case 0x4A: return HipKey.J; 404 case 0x4B: return HipKey.K; 405 case 0x4C: return HipKey.L; 406 case 0x4D: return HipKey.M; 407 case 0x4E: return HipKey.N; 408 case 0x4F: return HipKey.O; 409 case 0x50: return HipKey.P; 410 case 0x51: return HipKey.Q; 411 case 0x52: return HipKey.R; 412 case 0x53: return HipKey.S; 413 case 0x54: return HipKey.T; 414 case 0x55: return HipKey.U; 415 case 0x56: return HipKey.V; 416 case 0x57: return HipKey.W; 417 case 0x58: return HipKey.X; 418 case 0x59: return HipKey.Y; 419 case 0x5A: return HipKey.Z; 420 case VK_LWIN: return HipKey.META_LEFT; 421 case VK_RWIN: return HipKey.META_RIGHT; 422 //Maybe there's a need to change? 423 case VK_NUMPAD0: return HipKey._0; 424 case VK_NUMPAD1: return HipKey._1; 425 case VK_NUMPAD2: return HipKey._2; 426 case VK_NUMPAD3: return HipKey._3; 427 case VK_NUMPAD4: return HipKey._4; 428 case VK_NUMPAD5: return HipKey._5; 429 case VK_NUMPAD6: return HipKey._6; 430 case VK_NUMPAD7: return HipKey._7; 431 case VK_NUMPAD8: return HipKey._8; 432 case VK_NUMPAD9: return HipKey._9; 433 434 case VK_F1: return HipKey.F1; 435 case VK_F2: return HipKey.F2; 436 case VK_F3: return HipKey.F3; 437 case VK_F4: return HipKey.F4; 438 case VK_F5: return HipKey.F5; 439 case VK_F6: return HipKey.F6; 440 case VK_F7: return HipKey.F7; 441 case VK_F8: return HipKey.F8; 442 case VK_F9: return HipKey.F9; 443 case VK_F10: return HipKey.F10; 444 case VK_F11: return HipKey.F11; 445 case VK_F12: return HipKey.F12; 446 447 case VK_LSHIFT: return HipKey.SHIFT; 448 case VK_RSHIFT: return HipKey.SHIFT; 449 450 case VK_LCONTROL: return HipKey.CTRL; 451 case VK_RCONTROL: return HipKey.CTRL; 452 453 case VK_LMENU: return HipKey.ALT; 454 case VK_RMENU: return HipKey.ALT; 455 456 case VK_OEM_1: return HipKey.SEMICOLON; 457 458 case VK_OEM_COMMA: return HipKey.COMMA; 459 case VK_OEM_MINUS: return HipKey.MINUS; 460 case VK_OEM_PERIOD: return HipKey.PERIOD; 461 462 case VK_OEM_2: return HipKey.SLASH; 463 464 case VK_OEM_4: return HipKey.BRACKET_LEFT; 465 case VK_OEM_5: return HipKey.BACKSLASH; 466 case VK_OEM_6: return HipKey.BRACKET_RIGHT; 467 case VK_OEM_7: return HipKey.QUOTE; 468 case 0xFF: return HipKey.NONE; //Invalid 469 470 default: 471 version(HipCheckUnknownKeycode) 472 { 473 import hip.util.conv:to; 474 assert(false, "Unknown key received ("~to!string(k)~")"); 475 } 476 else 477 return cast(HipKey)k; 478 } 479 } 480 } 481 else static if(isLinuxPC) 482 { 483 public HipKey getHipKeyFromSystem(uint key) 484 { 485 import hip.windowing.platforms.x11lib.keysym; 486 switch(key) 487 { 488 case XK_BackSpace: return HipKey.BACKSPACE; 489 case XK_Tab: return HipKey.TAB; 490 case XK_Return: return HipKey.ENTER; 491 case XK_KP_Enter: return HipKey.ENTER; 492 case XK_Shift_L: return HipKey.SHIFT; 493 case XK_Shift_R: return HipKey.SHIFT; 494 case XK_Control_L: return HipKey.CTRL; 495 case XK_Control_R: return HipKey.CTRL; 496 case XK_Alt_L: return HipKey.ALT; 497 case XK_Alt_R: return HipKey.ALT; 498 case XK_Pause: return HipKey.PAUSE_BREAK; 499 case XK_Caps_Lock: return HipKey.CAPSLOCK; 500 case XK_Escape: return HipKey.ESCAPE; 501 case XK_space: return HipKey.SPACE; 502 case XK_Page_Up: return HipKey.PAGE_UP; 503 case XK_Page_Down: return HipKey.PAGE_DOWN; 504 case XK_End: return HipKey.END; 505 case XK_Home: return HipKey.HOME; 506 case XK_Left: return HipKey.ARROW_LEFT; 507 case XK_Up: return HipKey.ARROW_UP; 508 case XK_Right: return HipKey.ARROW_RIGHT; 509 case XK_Down: return HipKey.ARROW_DOWN; 510 case XK_Insert: return HipKey.INSERT; 511 case XK_Delete: return HipKey.DELETE; 512 case XK_0: return HipKey._0; 513 case XK_1: return HipKey._1; 514 case XK_2: return HipKey._2; 515 case XK_3: return HipKey._3; 516 case XK_4: return HipKey._4; 517 case XK_5: return HipKey._5; 518 case XK_6: return HipKey._6; 519 case XK_7: return HipKey._7; 520 case XK_8: return HipKey._8; 521 case XK_9: return HipKey._9; 522 case XK_A: return HipKey.A; 523 case XK_B: return HipKey.B; 524 case XK_C: return HipKey.C; 525 case XK_D: return HipKey.D; 526 case XK_E: return HipKey.E; 527 case XK_F: return HipKey.F; 528 case XK_G: return HipKey.G; 529 case XK_H: return HipKey.H; 530 case XK_I: return HipKey.I; 531 case XK_J: return HipKey.J; 532 case XK_K: return HipKey.K; 533 case XK_L: return HipKey.L; 534 case XK_M: return HipKey.M; 535 case XK_N: return HipKey.N; 536 case XK_O: return HipKey.O; 537 case XK_P: return HipKey.P; 538 case XK_Q: return HipKey.Q; 539 case XK_R: return HipKey.R; 540 case XK_S: return HipKey.S; 541 case XK_T: return HipKey.T; 542 case XK_U: return HipKey.U; 543 case XK_V: return HipKey.V; 544 case XK_W: return HipKey.W; 545 case XK_X: return HipKey.X; 546 case XK_Y: return HipKey.Y; 547 case XK_Z: return HipKey.Z; 548 case XK_a: return HipKey.A; 549 case XK_b: return HipKey.B; 550 case XK_c: return HipKey.C; 551 case XK_d: return HipKey.D; 552 case XK_e: return HipKey.E; 553 case XK_f: return HipKey.F; 554 case XK_g: return HipKey.G; 555 case XK_h: return HipKey.H; 556 case XK_i: return HipKey.I; 557 case XK_j: return HipKey.J; 558 case XK_k: return HipKey.K; 559 case XK_l: return HipKey.L; 560 case XK_m: return HipKey.M; 561 case XK_n: return HipKey.N; 562 case XK_o: return HipKey.O; 563 case XK_p: return HipKey.P; 564 case XK_q: return HipKey.Q; 565 case XK_r: return HipKey.R; 566 case XK_s: return HipKey.S; 567 case XK_t: return HipKey.T; 568 case XK_u: return HipKey.U; 569 case XK_v: return HipKey.V; 570 case XK_w: return HipKey.W; 571 case XK_x: return HipKey.X; 572 case XK_y: return HipKey.Y; 573 case XK_z: return HipKey.Z; 574 case XK_Meta_L: return HipKey.META_LEFT; 575 case XK_Meta_R: return HipKey.META_RIGHT; 576 case XK_F1: return HipKey.F1; 577 case XK_F2: return HipKey.F2; 578 case XK_F3: return HipKey.F3; 579 case XK_F4: return HipKey.F4; 580 case XK_F5: return HipKey.F5; 581 case XK_F6: return HipKey.F6; 582 case XK_F7: return HipKey.F7; 583 case XK_F8: return HipKey.F8; 584 case XK_F9: return HipKey.F9; 585 case XK_F10: return HipKey.F10; 586 case XK_F11: return HipKey.F11; 587 case XK_F12: return HipKey.F12; 588 case XK_semicolon: return HipKey.SEMICOLON; 589 case XK_equal: return HipKey.EQUAL; 590 case XK_comma: return HipKey.COMMA; 591 case XK_minus: return HipKey.MINUS; 592 case XK_period: return HipKey.PERIOD; 593 case XK_slash: return HipKey.SLASH; 594 case XK_bracketleft: return HipKey.BRACKET_LEFT; 595 case XK_bracketright: return HipKey.BRACKET_RIGHT; 596 case XK_backslash: return HipKey.BACKSLASH; 597 case XK_grave: return HipKey.QUOTE; 598 default: 599 { 600 version(HipCheckUnknownKeycode) 601 { 602 import hip.util.conv:to; 603 import hip.error.handler; 604 ErrorHandler.assertExit(false, "Unknown key received ("~to!string(key)~")"); 605 return cast(HipKey)0; 606 } 607 else 608 return cast(HipKey)key; 609 } 610 } 611 } 612 } 613 else version(WebAssembly) 614 { 615 public HipKey getHipKeyFromSystem(uint key) 616 { 617 ushort k = cast(ushort)(key); 618 assert(k > 0 && k <= ubyte.max, "Key out of range"); 619 switch(k) 620 { 621 case 8: return HipKey.BACKSPACE; 622 case 9: return HipKey.TAB; 623 case 27: return HipKey.ESCAPE; 624 625 626 case 13: return HipKey.ENTER; 627 case 20: return HipKey.CAPSLOCK; 628 case 32: return HipKey.SPACE; 629 case 33: return HipKey.PAGE_UP; 630 case 35: return HipKey.END; 631 case 36: return HipKey.HOME; 632 case 37: return HipKey.ARROW_LEFT; 633 case 38: return HipKey.ARROW_UP; 634 case 39: return HipKey.ARROW_RIGHT; 635 case 40: return HipKey.ARROW_DOWN; 636 case 45: return HipKey.INSERT; 637 case 46: return HipKey.DELETE; 638 //0 639 case 48: return HipKey._0; 640 case 49: return HipKey._1; 641 case 50: return HipKey._2; 642 case 51: return HipKey._3; 643 case 52: return HipKey._4; 644 case 53: return HipKey._5; 645 case 54: return HipKey._6; 646 case 55: return HipKey._7; 647 case 56: return HipKey._8; 648 case 57: return HipKey._9; 649 //A 650 case 65: return HipKey.A; 651 case 66: return HipKey.B; 652 case 67: return HipKey.C; 653 case 68: return HipKey.D; 654 case 69: return HipKey.E; 655 case 70: return HipKey.F; 656 case 71: return HipKey.G; 657 case 72: return HipKey.H; 658 case 73: return HipKey.I; 659 case 74: return HipKey.J; 660 case 75: return HipKey.K; 661 case 76: return HipKey.L; 662 case 77: return HipKey.M; 663 case 78: return HipKey.N; 664 case 79: return HipKey.O; 665 case 80: return HipKey.P; 666 case 81: return HipKey.Q; 667 case 82: return HipKey.R; 668 case 83: return HipKey.S; 669 case 84: return HipKey.T; 670 case 85: return HipKey.U; 671 case 86: return HipKey.V; 672 case 87: return HipKey.W; 673 case 88: return HipKey.X; 674 case 89: return HipKey.Y; 675 case 90: return HipKey.Z; 676 case 91: return HipKey.META_LEFT; 677 case 93: return HipKey.META_RIGHT; 678 //Maybe there's a need to change? 679 case 97: return HipKey._0; 680 case 98: return HipKey._1; 681 case 99: return HipKey._2; 682 case 100: return HipKey._3; 683 case 101: return HipKey._4; 684 case 102: return HipKey._5; 685 case 103: return HipKey._6; 686 case 104: return HipKey._7; 687 case 105: return HipKey._8; 688 case 106: return HipKey._9; 689 690 case 112: return HipKey.F1; 691 case 113: return HipKey.F2; 692 case 114: return HipKey.F3; 693 case 115: return HipKey.F4; 694 case 116: return HipKey.F5; 695 case 117: return HipKey.F6; 696 case 118: return HipKey.F7; 697 case 119: return HipKey.F8; 698 case 120: return HipKey.F9; 699 case 121: return HipKey.F10; 700 case 122: return HipKey.F11; 701 case 123: return HipKey.F12; 702 703 case 16: return HipKey.SHIFT; 704 case 17: return HipKey.CTRL; 705 case 18: return HipKey.ALT; 706 707 case 191: return HipKey.SEMICOLON; 708 709 case 188: return HipKey.COMMA; 710 case 189: return HipKey.MINUS; 711 case 190: return HipKey.PERIOD; 712 713 case 193: return HipKey.SLASH; 714 715 case 221: return HipKey.BRACKET_LEFT; 716 case 220: return HipKey.BRACKET_RIGHT; 717 case 226: return HipKey.BACKSLASH; 718 case 192: return HipKey.QUOTE; 719 case 0xFF: return HipKey.NONE; //Invalid 720 721 default: 722 version(HipCheckUnknownKeycode) 723 { 724 import hip.util.conv:to; 725 assert(false, "Unknown key received ("~to!string(k)~")"); 726 } 727 else 728 return cast(HipKey)k; 729 } 730 } 731 } 732 else version(AppleOS) 733 { 734 public HipKey getHipKeyFromSystem(uint key) 735 { 736 switch(key) 737 { 738 739 //Special Chars 740 case 0x31: return HipKey.SPACE; //space 741 case 0x24: return HipKey.ENTER; //returnKey 742 case 0x4C: return HipKey.ENTER; //enterKey 743 case 0x35: return HipKey.ESCAPE; //escape 744 case 0x38: return HipKey.SHIFT; //shift 745 case 0x37: return HipKey.ALT; //command 746 747 //DPad Keys 748 case 0x7B: return HipKey.ARROW_LEFT; //leftArrow 749 case 0x7C: return HipKey.ARROW_RIGHT; //rightArrow 750 case 0x7D: return HipKey.ARROW_DOWN; //downArrow 751 case 0x7E: return HipKey.ARROW_UP; //upArrow 752 753 //Alphabet 754 case 0x00: return HipKey.A; //a 755 case 0x0B: return HipKey.B; //b 756 case 0x08: return HipKey.C; //c 757 case 0x02: return HipKey.D; //d 758 case 0x0E: return HipKey.E; //e 759 case 0x03: return HipKey.F; //f 760 case 0x05: return HipKey.G; //g 761 case 0x04: return HipKey.H; //h 762 case 0x22: return HipKey.I; //i 763 case 0x26: return HipKey.J; //j 764 case 0x28: return HipKey.K; //k 765 case 0x25: return HipKey.L; //l 766 case 0x2E: return HipKey.M; //m 767 case 0x2D: return HipKey.N; //n 768 case 0x1F: return HipKey.O; //o 769 case 0x23: return HipKey.P; //p 770 case 0x0C: return HipKey.Q; //q 771 case 0x0F: return HipKey.R; //r 772 case 0x01: return HipKey.S; //s 773 case 0x11: return HipKey.T; //t 774 case 0x20: return HipKey.U; //u 775 case 0x09: return HipKey.V; //v 776 case 0x0D: return HipKey.W; //w 777 case 0x07: return HipKey.X; //x 778 case 0x10: return HipKey.Y; //y 779 case 0x06: return HipKey.Z; //z 780 781 //Top Numbers 782 case 0x1D: return HipKey._0;//zero 783 case 0x12: return HipKey._1; //one 784 case 0x13: return HipKey._2;//two 785 case 0x14: return HipKey._3;//three 786 case 0x15: return HipKey._4;//four 787 case 0x17: return HipKey._5;//five 788 case 0x16: return HipKey._6;//six 789 case 0x1A: return HipKey._7;//seven 790 case 0x1C: return HipKey._8;//eight 791 case 0x19: return HipKey._9;//nine 792 793 //Keypad Numbers 794 case 0x52: return HipKey._0; //keypad0 795 case 0x53: return HipKey._1; //keypad1 796 case 0x54: return HipKey._2; //keypad2 797 case 0x55: return HipKey._3; //keypad3 798 case 0x56: return HipKey._4; //keypad4 799 case 0x57: return HipKey._5; //keypad5 800 case 0x58: return HipKey._6; //keypad6 801 case 0x59: return HipKey._7; //keypad7 802 case 0x5B: return HipKey._8; //keypad8 803 case 0x5C: return HipKey._9; //keypad9 804 case 0xFF: return HipKey.NONE; //Invalid 805 default: 806 // version(HipCheckUnknownKeycode) 807 // { 808 // import hip.console.log; 809 // loglnError("Unknown key received ("~to!string(k)~")"); 810 // assert(false, "Unknown key received ("~to!string(k)~")"); 811 // } 812 // else 813 return cast(HipKey)key; 814 815 } 816 } 817 } 818 else version(PSVita) 819 { 820 public HipKey getHipKeyFromSystem(uint key){return HipKey._0;} 821 } 822 else public HipKey getHipKeyFromSystem(uint key){return HipKey._0;} 823